/*Shift-JIS*/
/*UTF-8*/
/********************************************************************************/
/*ソース名:                                                                       */
/*　　pf_file.c                                                                   */
/*機能:                                                                         */
/*　　ファイルを管理するモジュール 　　　　　　　　　　　　　　　　                                                                                     */
/*作成者:                                                                       */
/*　　2010/06 関（CBSﾃｸﾉ）                                                                                                                                       */
/********************************************************************************/
/********************************************************************************/
/*変更履歴:                                                                     */
/*  COXから流用                                                                                                                                                           */
/*　　FildFind***　関数を追加                                                                                                                               */
/********************************************************************************/

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include <time.h>
#include <errno.h>
#include "typedef.h"
#include "Id.h"
#include "lib_func.h"
#include "core.h"
#include "./textfile/pf_file.h"

/******************************************
 * 各種の定数定義
 *****************************************/


#define cFILEHANDLE_INIT 		((FILE*)NULL)	/* 初期値、ﾌｧｲﾙ未ｵｰﾌﾟﾝ		*/
#define cFLMOD_INIT				((U2)0)	/* ｵｰﾌﾟﾝﾓｰﾄﾞ初期値		*/
#define cSIZE_FILECACHE		(1024*8)
#define cSIZE_TEMPBUF		(2048)
#define cSIZE_READBUF		(2048<<6)
#define IsDouble_byte(a) (a & (0x80) )


/******************************************
 * static変数定義
 *****************************************/

/*_____[ ﾌｧｲﾙﾏﾈｰｼﾞｬ管理ﾃｰﾌﾞﾙ ]__________________________________________*/
typedef struct _FILEMANAGE
{
	HFILE		hFile;		/* ﾌｧｲﾙﾊﾝﾄﾞﾙ			    */
	U2		usOpenMode;	/* ｵｰﾌﾟﾝﾓｰﾄﾞ			    */
					        /* ﾌｧｲﾙ名ﾌﾙﾊﾟｽ	        */
	CHAR		szFullPath[OS_FULLPATH+1];
	FILE*		iHandle;	/* ﾌｧｲﾙﾊﾝﾄﾞﾙ			    */
	PBYTE		pbyCache;	/* ｷｬｯｼｭﾊﾞｯﾌｧへのﾎﾟｲﾝﾀ		*/
	U4		ulOffset;	/* ﾊﾞｯﾌｧﾃﾞｰﾀ位置始点		*/
	U4		ulBuffSize;	/* ﾊﾞｯﾌｧﾃﾞｰﾀ位置終点		*/
} FILEMANAGE, *PFILEMANAGE;
static FILEMANAGE	stFileManage[cMAX_FILEMANAGE];
static CHAR		uchFileTmpBuff[cSIZE_TEMPBUF];	/* ﾌｧｲﾙﾏﾈｰｼﾞｬ用ﾜｰｸﾊﾞｯﾌｧ		*/
static S4		iFileError = 0;
static CHAR     filecache[cMAX_FILEMANAGE][cSIZE_FILECACHE];
static CHAR     readbuf[cSIZE_READBUF] = "";
static U4     readbuf_usedsize = 0;
static BOOL		initialed = FALSE;
/******************************************
 * extern変数定義
 *****************************************/

/******************************************
 * static 関数 プロトタイプ宣言
 *****************************************/
static PSZ	getPathDelimiter( PSZ , BOOL  );
static PFILEMANAGE	getFileManage( HFILE );
static S4	flushCache( PFILEMANAGE );
static S4	readCache( PFILEMANAGE );
static S4	fileMakeDir( PSZ );

/*******************************************
 *static関数定義
 *******************************************/

/*D*/
/********************************************
 *関数名：getPathDelimiter(新規）
 *パラメータ：
 *		pszPath  パスの文字列の起点の位置を示す
 *		bForward TRUEの場合、一番前のデリミタの位置を取得
 *					FALSEの場合、一番後のデリミタの位置を取得
 *戻り値：
 *		該当するデリミタの位置
 *		空文字列の場合：NULL
 *		デリミタ無しの場合：NULL
 *機能：
 *		パス名中の一番目のデリミタ又は最後のデリミタを取得。
 *		パス中の空白、日本語に対応する。
 ************************************************/

static PSZ	getPathDelimiter( PSZ pszPath, BOOL bForward )
{
	register PSZ p;

	/* 空文字列 */
	if( pszPath == NULL )
	{
		return NULL;
	}
	else if ( *pszPath == 0 )
	{
		return NULL;
	}

	if ( bForward == TRUE )
	{
		p = pszPath;
		while( *p != '\0' )
		{
			if(IS_91_CHAR(*p)){
				if( IS_PATH_DELIMITER(*p) )
				{
					return( p );
				}
			}else if( IS_MULTI_CHAR( *p ) ){
				p++;
			}
			p++;
		}
	}else
	{
		p = pszPath + (S4)(strlen(pszPath)-1);
		while( (ptrdiff_t)( p - pszPath ) > 0 )
		{
			if(!IS_MULTI_CHAR(*(p-1))){
				if( IS_PATH_DELIMITER(*p) )
				{
					return( p );
				}
			}else{
				p--;
			}
			p--;
		}
	}

	return( NULL );
}

/********************************************
* 関 数 名 : getFileManage（完全流用）
* 機    能 : 指定ﾌｧｲﾙの管理ﾃｰﾌﾞﾙｱﾄﾞﾚｽ取得
* 引 き 数 : HFILE       hFile             ﾌｧｲﾙID
* 戻 り 値 : PFILEMANAGE *ppstFileManage   ﾌｧｲﾙﾏﾈｰｼﾞｬ管理ﾃｰﾌﾞﾙ(ﾎﾟｲﾝﾀ)
* 詳細内容 : 1. hFile－１を添え字にして、管理ﾃｰﾌﾞﾙのｱﾄﾞﾚｽを取得する。
*          : ※ hFileは管理ﾃｰﾌﾞﾙの添え字＋１になっている。
*******************************************************************/
/*d*/
static PFILEMANAGE	getFileManage( HFILE hFile )
{
	if( ( hFile < 1 ) || ( hFile > cMAX_FILEMANAGE ) ){
		return NULL;
	}
	return( &stFileManage[hFile-1] );
}

/*d*/
/*********************************************
* 関 数 名 : flushCache（修正有）
* 機    能 : ﾊﾞｯﾌｧﾃﾞｰﾀのﾘｾｯﾄ
* 引 き 数 : PFILEMANAGE pstFileManage     ﾌｧｲﾙﾏﾈｰｼﾞｬ管理ﾃｰﾌﾞﾙ
* 戻 り 値 : S4         COEXIT_SUCCESS    正常終了
*          :             COEXIT_FATAL     異常終了
* 詳細内容 : 1. ｵｰﾌﾟﾝﾓｰﾄﾞにﾘｰﾄﾞﾌﾗｸﾞが立っていないときはﾊﾞｯﾌｧﾃﾞｰﾀをﾌｧｲﾙ
*          :   へ出力する。
*          : 2. ﾊﾞｯﾌｧﾃﾞｰﾀのｵﾌｾｯﾄとﾊﾞｯﾌｧｻｲｽﾞをﾘｾｯﾄする。
***********************************************************************/
/*d*/
static S4	flushCache( PFILEMANAGE pstFileManage )
{
	size_t 			sRet;	/* writeの戻り値	（修正:型変更 ssize_t -> long)	*/

    /* 書き込み用ﾊﾞｯﾌｧの内容をﾌｧｲﾙにﾌﾗｯｼｭする			*/
	if( !( pstFileManage->usOpenMode & FLMOD_READONLY )
			&& !( pstFileManage->usOpenMode & FLMOD_BIN_READONLY )
			&& pstFileManage->ulBuffSize > 0 )
	{
		/*（修正:ライブラリ関数変更 write -> fwrite)	*/
		sRet = fwrite( pstFileManage->pbyCache, 1,
			      (size_t)pstFileManage->ulBuffSize, (FILE*)pstFileManage->iHandle );
		if( sRet < (size_t)(pstFileManage->ulBuffSize ))
		{
			iFileError = FMERROR_WRITEFILE;
			return( COEXIT_FATAL );
		}
	}

	/* ﾃﾞｰﾀｻｲｽﾞとﾃﾞｰﾀｵﾌｾｯﾄをﾘｾｯﾄする				*/
	pstFileManage->ulBuffSize = 0L;
	pstFileManage->ulOffset = 0L;

	return( COEXIT_SUCCESS );
}

/*d*/
/******************************************
* 関 数 名 : readCache（修正有）
* 機    能 : ｷｬｼｭﾊﾞｯﾌｧへのREAD
* 引 き 数 : PFILEMANAGE pstFileManage     ﾌｧｲﾙﾏﾈｰｼﾞｬ管理ﾃｰﾌﾞﾙ
* 戻 り 値 : S4         COEXIT_SUCCESS    正常終了
*          :             COEXIT_FILEEND    ﾌｧｲﾙｴﾝﾄﾞ
*          :             COEXIT_FATAL     異常終了
* 詳細内容 : 1. ｷｬｯｼｭﾊﾞｯﾌｧのｻｲｽﾞ分READする。
*          : 2. 指定ﾌｧｲﾙの開始位置/終了位置をﾘｾｯﾄする。
***********************************************************************/
/*d*/
static S4	readCache( PFILEMANAGE pstFileManage )
{
	S4			rc;		/* この関数の戻り値		*/
	size_t 		sRet;		/* readの戻り値	（修正:型変更 ssize_t -> long)	*/
	U4		ulBufferSize;	/* 指定ﾌｧｲﾙのﾊﾞｯﾌｧｻｲｽﾞ		*/

	ulBufferSize = (U4)( cSIZE_FILECACHE );
					/* 格納ｷｬｯｼｭﾊﾞｯﾌｧｻｲｽﾞの取得	*/

	/*（修正:ライブラリ関数変更 read -> fread)	*/
	sRet = fread( pstFileManage->pbyCache, 1, ulBufferSize, (FILE *)pstFileManage->iHandle );
	/*（修正:READエラー判断  変更前：if(sRet < 0) */
	if( ferror((FILE *)pstFileManage->iHandle) )			/* "READｴﾗｰ" だった時		*/
	{
		iFileError = FMERROR_READFILE;
		return( COEXIT_FATAL );
	}
	else if( sRet == 0 )
	{
		rc = COEXIT_FILEEND;
	}
	else
	{
		rc = COEXIT_SUCCESS;
	}

	/*** ﾃﾞｰﾀの開始、終端位置をｾｯﾄ	***/
	pstFileManage->ulOffset = 0L;
	pstFileManage->ulBuffSize = (U4)sRet;

	return( rc );
}
/*d*/
/********************************************************************
* 関 数 名 : fileMakeDir（修正有）
* 機    能 : ﾊﾟｽ名(ﾌｧｲﾙ名込み)で指定されたﾃﾞｨﾚｸﾄﾘを作成
* 引 き 数 : PSZ       pszPath        作成するﾃﾞｨﾚｸﾄﾘ(ﾌｧｲﾙ名込み)
* 戻 り 値 : S4       COEXIT_SUCCESS 正常終了
*          :           COEXIT_FATAL  異常終了
* 詳細内容 : 1. ﾊﾟｽ名からﾃﾞｨﾚｸﾄﾘ部分を取り出す。
*          : 2. 最初から順番にﾃﾞｨﾚｸﾄﾘを作成していく。
*          : 3. ﾃﾞｨﾚｸﾄﾘがすでに存在した場合は、無視して続ける。
***********************************************************************/
/*d*/
static S4	fileMakeDir( PSZ pszPath )
{
	CHAR		buf[OS_FULLPATH + 1];
	PSZ		p;

#if  (__OS__ == _WINDOWS_XP ) || (__OS__ == _WINDOWS_7)
	PSZ		p1;
	CHAR		ctemp;
	S4		iFullPath=0;
#endif
	/* 一時バッファーにコピー */
	strncpy( buf, pszPath, OS_FULLPATH );

	/* ファイル名削除 開始*/
	/* 変更: strrchr -> getPathDelimiter */
	p = getPathDelimiter( buf, FALSE );
	if( p == NULL )
	{
		return( COEXIT_SUCCESS );
	}
	*( p + 1 ) = '\0';
	/* ファイル名削除 終了*/

	/* 追加：パス種類の認識 　START*/
#if  (__OS__ == _WINDOWS_XP ) || (__OS__ == _WINDOWS_7)
	p = buf;
	if (  buf[0] == '\\' && buf[1] == '\\' )
	{
		p = p + 2;
		iFullPath = 2;  /* network */
	}
	if ( buf[1] == ':' )
	{
		p = p + 3;
		iFullPath = 3; /* local */
	}
#else
	p = strchr( buf, '/' );
#endif
	/* 追加：パス種類の認識 END*/

	/* 変更: strrchr -> getPathDelimiter */
	p = getPathDelimiter( p, TRUE );
	while( p != NULL )
	{
#if  (__OS__ == _WINDOWS_XP ) || (__OS__ == _WINDOWS_7)
		/* 変更: p == buf  -> p == ( buf + iFullPath ) */
		if( p == ( buf + iFullPath ) )
#else
		if( p == buf )
#endif
		{
#if  (__OS__ == _WINDOWS_XP ) || (__OS__ == _WINDOWS_7)
			/* 変更: strrchr -> getPathDelimiter */
			p1 = getPathDelimiter( p+1, TRUE );
			/*　追加：連続\\ に対応 S*/
			while ( p1 == ( p+1 ) )
			{
				p=p1;
				p1 = getPathDelimiter( p+1, TRUE );
			}
			/*　追加：連続\\ に対応 E*/
			p = p1;
#else
			p = strchr( p + 1, '/' );
#endif
			if ( p == NULL )
			{		/*  ﾙｰﾄのﾌｧｲﾙのようだ		*/
				return( COEXIT_SUCCESS );
			}
		}
#if  (__OS__ == _WINDOWS_XP ) || (__OS__ == _WINDOWS_7)
		/*　追加：元のデリミタを保持 S*/
		ctemp = *p;
		/*　追加：元のデリミタを保持 E*/
#endif
		*p = '\0';
		/*  変更：ライブラリ関数　mkdir -> _mkdir */
		if( makenewdir( buf ) < 0 )
		{
			if( errno != EEXIST )
			{
				iFileError = FMERROR_MAKEDIR;
				return( COEXIT_FATAL );
			}
		}
#if  (__OS__ == _WINDOWS_XP ) || (__OS__ == _WINDOWS_7)
		*p = ctemp;
#else
		*p = '/';
#endif
#if  (__OS__ == _WINDOWS_XP ) || (__OS__ == _WINDOWS_7)
		/* 変更: strrchr -> getPathDelimiter */
		p1 = getPathDelimiter( p+1, TRUE );
		/*　追加：連続\\ に対応 S*/
		while ( p1 == ( p+1 ) )
		{
			p = p1;
			p1 = getPathDelimiter( p+1, TRUE );
		}
		/*　追加：連続\\ に対応 E*/
		p = p1;
#else
		p = strchr( p + 1, '/' );
#endif
	}
	return( COEXIT_SUCCESS );
}
/*D*/
/*[ FILEMAN-USER-008        ]********************************************/
/* 関 数 名 : fileReadLine                                              */
/* 機    能 : ﾌｧｲﾙからの１行読み込み                                    */
/* 引 き 数 : HFILE       hFile             ﾌｧｲﾙﾊﾝﾄﾞﾙ                   */
/*          : PUCHAR      puchBuff          ﾃﾞｰﾀ読み込み領域            */
/*          : U4       ulSize            読み込み最大ｻｲｽﾞ            */
/* 戻 り 値 : S4         COEXIT_SUCCESS    正常終了                    */
/*          :             COEXIT_FILEEND    ﾌｧｲﾙｴﾝﾄﾞ                    */
/*          :             COEXIT_FATAL     異常終了                    */
/* 詳細内容 : 1. 指定ﾌｧｲﾙの管理ﾃｰﾌﾞﾙｱﾄﾞﾚｽを取得する。                   */
/*          : 2. '\n'の出現、ﾌｧｲﾙの終端または格納ｻｲｽﾞが ulSize-1 に達す */
/*          :    るまで１ﾊﾞｲﾄずつﾊﾞｯﾌｧﾃﾞｰﾀをｺﾋﾟｰする。                  */
/*          : 3. ﾊﾞｯﾌｧﾃﾞｰﾀが無くなったときはﾌｧｲﾙから読み込み、繰り返す。*/
/*          : 4. 管理ﾃｰﾌﾞﾙの取得に失敗したときは異常終了する。          */
/*          : 5. ﾌｧｲﾙｵｰﾌﾟﾝされていないときは異常終了する。              */
/*          : 6. ｵｰﾌﾟﾝﾓｰﾄﾞに読み込み許可がないときは異常終了する。      */
/*          : 7. すでにﾌｧｲﾙの最後に達していたときはﾌｧｲﾙｴﾝﾄﾞを返す。     */
/*          : 8. ﾌｧｲﾙから指定ｻｲｽﾞのﾃﾞｰﾀを読み込めないときは、ｴﾗｰﾒｯｾｰｼﾞを*/
/*          :    出力して異常終了する。                                 */
/*          : 9. ﾌｧｲﾙから指定ｻｲｽﾞのﾃﾞｰﾀを読み込む前にﾌｧｲﾙｴﾝﾄﾞに達したと */
/*          :    きは、ｴﾗｰﾒｯｾｰｼﾞを出力して異常終了する。                */
/************************************************************************/
/*D*/
static S4	fileReadLine( HFILE hFile, CHAR* puchBuff, U4 ulSize, U4 *pulLength )
{
	U4			ulDataSize;	/* ﾊﾞｯﾌｧのﾃﾞｰﾀｻｲｽﾞ		*/
	register U4	ulCnt;		/* puchBuff への格納ｻｲｽﾞ	*/
	S4				iRet;		/* ﾕ-ｻﾞ関数の戻り値		*/
	register		PFILEMANAGE	pstFileManage;	/* 読み込むﾌｧｲﾙの管理ﾃｰﾌﾞﾙｱﾄﾞﾚｽ	*/
	register CHAR*	pszBuffP;	/* 出力ﾊﾞｯﾌｧのﾎﾟｲﾝﾀ		*/
	register CHAR*	puchCopy;

	/*** 指定の管理ﾃｰﾌﾞﾙを取得	***/
	pstFileManage = getFileManage( hFile );
	if( pstFileManage == NULL )
	{
		iFileError = FMERROR_ILLEGALHANDLE;
		return( COEXIT_FATAL );
	}

	/*** OPENされていない時は、不可	***/
	if( pstFileManage->iHandle == cFILEHANDLE_INIT )
	{
		iFileError = FMERROR_ACCESS_CLOSEDFILE;
		return( COEXIT_FATAL );
	}

	/*** 読み込み許可でない時、不可	***/
	if( !( pstFileManage->usOpenMode & FLMOD_READONLY ) )
	{
		iFileError = FMERROR_READ_WRITEONLYFILE;
		return( COEXIT_FATAL );
	}

	ulCnt = 0L;
	pszBuffP = puchBuff;
	puchCopy = (CHAR*)(PVOID)( pstFileManage->pbyCache + pstFileManage->ulOffset );

	/*** 指定ｻｲｽﾞREADする		***/
	while( ulCnt < ( ulSize - 1 ) )
	{
		/*** ﾊﾞｯﾌｧにﾃﾞｰﾀがない時 READする	***/
		ulDataSize = pstFileManage->ulBuffSize - pstFileManage->ulOffset;
		if( ulDataSize == 0 )
		{
			/*** ｷｬｼｭﾊﾞｯﾌｧへの読み込み	***/
			iRet = readCache( pstFileManage );
			if( iRet == COEXIT_FILEEND )
			{
				if( ulCnt == 0L )
				{
					*pszBuffP = '\0';
					return( iRet );
				}
				else
				{
					break;
				}
			}
			else if( iRet != COEXIT_SUCCESS )
			{
				return( iRet );
			}

			/*** ﾃﾞｰﾀｻｲｽﾞを再ｾｯﾄ		***/
			ulDataSize = pstFileManage->ulBuffSize;
			puchCopy = (CHAR*)(PVOID)( pstFileManage->pbyCache + pstFileManage->ulOffset );
		}

		/*** 1BYTE分READする		***/
		*pszBuffP = *puchCopy;
		puchCopy++;

		pstFileManage->ulOffset++;

		/*** 改行記号を格納した		***/
		if( *pszBuffP == '\n' )
		{
			pszBuffP++;
			ulCnt++;
			break;
		}

		pszBuffP++;
		ulCnt++;
	}

	*pszBuffP = '\0';
	if( pulLength != NULL )
	{
		*pulLength = ulCnt;
	}

	return( COEXIT_SUCCESS );
}

/***************************************************
 * 公開関数定義
************************************************* */
/***************************************************
* 関 数 名 : FileIsInitialized
* 機    能 : ﾌｧｲﾙﾏﾈｰｼﾞｬ管理ﾃｰﾌﾞﾙの初期化したかをチェックする
* 引 き 数 :
* 戻 り 値 : S4         COEXIT_SUCCESS    正常終了
*          :             COEXIT_FATAL     異常終了
************************************************************************/
/*D*/
BOOL		FileIsInitialized( VOID )
{
	return initialed;
}
/***************************************************
* 関 数 名 : FileInitialize
* 機    能 : ﾌｧｲﾙﾏﾈｰｼﾞｬ管理ﾃｰﾌﾞﾙの初期化
* 引 き 数 : U2      usProcID          呼び出し元ﾌﾟﾛｾｽID
* 戻 り 値 : S4         COEXIT_SUCCESS    正常終了
*          :             COEXIT_FATAL     異常終了
* 詳細内容 : 1. ﾃﾝﾎﾟﾗﾘﾒﾓﾘのｱｸｾｽ許可申請をする。
*          : 2. ｷｬｯｼｭﾊﾞｯﾌｧ用のﾃﾝﾎﾟﾗﾘﾒﾓﾘを確保する。
*          : 3. 確保したﾃﾝﾎﾟﾗﾘﾒﾓﾘを管理ﾃｰﾌﾞﾙに割り当てる。
*          : 4. ﾃﾝﾎﾟﾗﾘﾒﾓﾘのｱｸｾｽ許可が得られないときは異常終了する。
*          : 5. ﾃﾝﾎﾟﾗﾘﾒﾓﾘの確保に失敗したときは異常終了する。
************************************************************************/
/*D*/
S4		FileInitialize( VOID )
{
	S4		i;		/* ｶｳﾝﾀ				*/

	if( initialed )
	{
		return COEXIT_SUCCESS;
	}
	/*_____[ 各ｷｬｯｼｭに領域割り当て ]________________________________*/
	for( i = 0; i < cMAX_FILEMANAGE; i ++ )
	{
		stFileManage[i].hFile = (HFILE)( i + 1 );
		stFileManage[i].iHandle = cFILEHANDLE_INIT;
		stFileManage[i].usOpenMode = cFLMOD_INIT;
		stFileManage[i].pbyCache = (PBYTE)filecache[i];
	}
	initialed = 1;
	return( COEXIT_SUCCESS );
}

/*D*/
/*******************************************/
/* 関 数 名 : FileTerminate                                             */
/* 機    能 : ﾌｧｲﾙﾏﾈｰｼﾞｬ管理ﾃｰﾌﾞﾙの解放                                 */
/* 引 き 数 : なし                                                      */
/* 戻 り 値 : S4         COEXIT_SUCCESS    正常終了                    */
/*          :             COEXIT_FATAL     エラー                      */
/* 詳細内容 : 1. ｵｰﾌﾟﾝされているﾌｧｲﾙが存在しないかをﾁｪｯｸする。          */
/*          : 2. ﾃﾝﾎﾟﾗﾘﾒﾓﾘをｸﾛｰｽﾞする。                                 */
/*          : 3. ｸﾛｰｽﾞされていないﾌｧｲﾙはｸﾛｰｽﾞ処理をして最後にｴﾗｰを返す。*/
/*          : 4. ﾃﾝﾎﾟﾗﾘﾒﾓﾘのｸﾛｰｽﾞに失敗したときは最後にｴﾗｰを返す。      */
/************************************************************************/
/*D*/
S4		FileTerminate( VOID )
{
	S4		i;		/* ｶｳﾝﾀ				*/
	S4		iRetVal;	/* FileTerminate の戻り値	*/

	iRetVal = COEXIT_SUCCESS;	/* 戻り値の初期化		*/
	if( !initialed )
	{
		return COEXIT_SUCCESS;
	}
	/*** ｵｰﾌﾟﾝされているﾌｧｲﾙは全てｸﾛｰｽﾞ	***/
	for( i = 0; i < cMAX_FILEMANAGE; i++ )
	{
		if( stFileManage[i].iHandle != cFILEHANDLE_INIT )
		{
			FileClose( stFileManage[i].hFile );
			iRetVal = COEXIT_FATAL;
			iFileError = iFileError?iFileError:FMERROR_NOTCLOSE;
		}
	}
	initialed = 0;
	return( iRetVal );
}
/*D*/
/********************************************/
/* 関 数 名 : FileOpen                                                  */
/* 機    能 : 指定ﾌｧｲﾙをｵｰﾌﾟﾝ                                           */
/* 引 き 数 : PSZ         pszFileName       ﾌｧｲﾙ名                      */
/*          : U2      usOpenMode        ｵｰﾌﾟﾝﾓｰﾄﾞ                   */
/*          :               FLMOD_READ      : 読み込み専用              */
/*          :               FLMOD_WRITE     : 書き込み専用              */
/*          :               FLMOD_READWRITE : 読み書き両用              */
/*          :               FLMOD_APPEND    : 追加書き込み              */
/*          : PHFILE      phFile            ﾌｧｲﾙﾊﾝﾄﾞﾙ(戻り)             */
/* 戻 り 値 : S4         COEXIT_SUCCESS    正常終了                    */
/*          :             COEXIT_FATAL     異常終了                    */
/* 詳細内容 : 1. 指定ﾌｧｲﾙの管理ﾃｰﾌﾞﾙｱﾄﾞﾚｽを取得する。                   */
/*          : 2. 引数のｵｰﾌﾟﾝﾓｰﾄﾞを open関数のｵｰﾌﾟﾝﾓｰﾄﾞの形式に変換する。*/
/*          : 3. ﾌｧｲﾙをｵｰﾌﾟﾝする。                                      */
/*          : 4. ﾌｧｲﾙﾊﾝﾄﾞﾙ、引数のｵｰﾌﾟﾝﾓｰﾄﾞを管理ﾃｰﾌﾞﾙにｾｯﾄする。       */
/*          : 5. 管理ﾃｰﾌﾞﾙの取得に失敗したときは異常終了する。          */
/*          : 6. ﾌｧｲﾙがすでにｵｰﾌﾟﾝされていたときは異常終了する。        */
/*          : 7. ｵｰﾌﾟﾝﾓｰﾄﾞが定義されたものではないときは異常終了する。  */
/*          : 8. ﾌｧｲﾙｵｰﾌﾟﾝに失敗したときは、ｴﾗｰﾒｯｾｰｼﾞを出力して異常終了 */
/*          :    する。                                                 */
/************************************************************************/
/*D*/
S4		FileOpen( PSZ pszFileName, U2 usOpenMode, HFILE *phFile )
{
	CHAR	*cMode;		/* 形式変換後のｵｰﾌﾟﾝﾓｰﾄﾞ	*/
	S4		i;		/* ｶｳﾝﾀ				*/
	FILEMANAGE	*pstFileManage=NULL;
	S4		iRc;
	FILE*	pFile;

	if( !initialed )
	{
		iFileError =  FMERROR_NOT_BE_INITIALIZED;
		return COEXIT_FATAL;
	}
	for( i = 0; i < cMAX_FILEMANAGE; i++ )
	{
		if( stFileManage[i].iHandle == cFILEHANDLE_INIT )
		{
			pstFileManage = &stFileManage[i];
			break;
		}
	}

	if( i == cMAX_FILEMANAGE )
	{
		iFileError = FMERROR_NOROOMFORNEW;
		return( COEXIT_FATAL );
	}

	if (( pszFileName == NULL )||( *pszFileName == '\0' ))
	{
		iFileError = FMERROR_EMPTYPATH;
		return( COEXIT_FATAL );
	}

	/* ﾌｧｲﾙ名の長さをﾁｪｯｸしてから、ﾌｧｲﾙ名を格納			*/
	if( sizeof(pstFileManage->szFullPath) <= strlen(pszFileName) )
	{
		iFileError = FMERROR_ILLEGALPATH;
		return( COEXIT_FATAL );
	}

	strcpy( pstFileManage->szFullPath, pszFileName );

	memset( pstFileManage->pbyCache, 0, (size_t)(cSIZE_FILECACHE) );

	/*** OPEN ﾓｰﾄﾞの取得		***/
	switch( usOpenMode )
	{
	case FLMOD_READONLY:		/* 読み込み専用			*/
		cMode = "r";
		break;

	case FLMOD_WRITEONLY:		/* 書き込み専用			*/
		cMode = "w";
		/*** ﾌｧｲﾙをｵｰﾌﾟﾝするﾃﾞｨﾚｸﾄﾘを作成する	***/
		iRc = fileMakeDir( pszFileName );
		if( iRc != COEXIT_SUCCESS )
		{
			return( COEXIT_FATAL );
		}
		break;
	case FLMOD_APPEND:		/* 追加				*/
		cMode = "a";
		break;
	case FLMOD_BIN_READONLY:		/* 読み込み専用			*/
		cMode = "rb";
		break;

	case FLMOD_BIN_WRITEONLY:		/* 書き込み専用			*/
		cMode = "wb";
		/*** ﾌｧｲﾙをｵｰﾌﾟﾝするﾃﾞｨﾚｸﾄﾘを作成する	***/
		iRc = fileMakeDir( pszFileName );
		if( iRc != COEXIT_SUCCESS )
		{
			return( COEXIT_FATAL );
		}
		break;
	case FLMOD_BIN_APPEND:		/* 追加				*/
		cMode = "ab";
		break;
	default:
		iFileError = FMERROR_ILLEGALOPENMODE;
		return( COEXIT_FATAL );
	}

	pFile = fopen( pstFileManage->szFullPath, cMode );
	if( pFile ==NULL )
	{
		iFileError = FMERROR_OPENFILE;
		return( COEXIT_FATAL );
	}

	/*** ﾌｧｲﾙﾊﾝﾄﾞﾙ、ｵｰﾌﾟﾝﾓｰﾄﾞのｾｯﾄ	***/
	pstFileManage->iHandle		= pFile;
	pstFileManage->usOpenMode	= usOpenMode;

	/*** ﾊﾞｯﾌｧのﾘｾｯﾄ		***/
	pstFileManage->ulBuffSize	= 0L;
	pstFileManage->ulOffset		= 0L;

	if(phFile)
	{
		*phFile = pstFileManage->hFile;
	}

	return( COEXIT_SUCCESS );
}

/*D*/
/*[ FILEMAN-USER-004        ]********************************************/
/* 関 数 名 : FileClose                                                 */
/* 機    能 : 指定ﾌｧｲﾙをｸﾛｰｽﾞ                                           */
/* 引 き 数 : HFILE       hFile             ﾌｧｲﾙﾊﾝﾄﾞﾙ                   */
/* 戻 り 値 : S4         COEXIT_SUCCESS    正常終了                    */
/*          :             COEXIT_FATAL     異常終了                    */
/* 詳細内容 : 1. 指定ﾌｧｲﾙの管理ﾃｰﾌﾞﾙｱﾄﾞﾚｽを取得する。                   */
/*          : 2. ｷｬｯｼｭﾃﾞｰﾀをﾘｾｯﾄ                                        */
/*          : 3. ﾌｧｲﾙをｸﾛｰｽﾞする。                                      */
/*          : 4. ﾌｧｲﾙﾊﾝﾄﾞﾙ、ｵｰﾌﾟﾝﾓｰﾄﾞをﾘｾｯﾄする。                       */
/*          : 5. 管理ﾃｰﾌﾞﾙの取得に失敗したときは異常終了する。          */
/*          : 6. 指定ﾌｧｲﾙがｵｰﾌﾟﾝされていないときは異常終了する。        */
/*          : 7. ﾊﾞｯﾌｧﾃﾞｰﾀの書き込みに失敗したときは最後まで処理を行い、*/
/*          :    異常終了する。                                         */
/*          : 8. ﾌｧｲﾙｸﾛｰｽﾞに失敗したときは最後まで処理を行い、異常終了す*/
/*          :    る。                                                   */
/************************************************************************/
/*D*/
S4		FileClose( HFILE hFile )
{
	S4		iRet;		/* 戻り値			*/
	S4		iRetVal;	/* 戻り値			*/
	PFILEMANAGE	pstFileManage;	/* ｸﾛｰｽﾞしたいﾌｧｲﾙのﾃｰﾌﾞﾙｱﾄﾞﾚｽ	*/

	if( !initialed )
	{
		iFileError =  FMERROR_NOT_BE_INITIALIZED;
		return COEXIT_FATAL;
	}

	/*** 指定の管理ﾃｰﾌﾞﾙ取得	***/
	pstFileManage = getFileManage( hFile );
	if( pstFileManage == NULL )
	{
		iFileError = FMERROR_ILLEGALHANDLE;
		return( COEXIT_FATAL );
	}

	/*** OPENしていない時 CLOSE不可	***/
	if( pstFileManage->iHandle == cFILEHANDLE_INIT )
	{
		return( COEXIT_SUCCESS );
	}

	iRetVal = COEXIT_SUCCESS;	/* 戻り値の初期化		*/

	/*** ｷｬｼｭｻｲｽﾞのﾘｾｯﾄ処理		***/
	iRet = flushCache( pstFileManage );
	if( iRet != COEXIT_SUCCESS )
	{
		iRetVal = COEXIT_FATAL;
	}

	/*** ﾌｧｲﾙｸﾛｰｽﾞ処理		***/
	iRet = fclose( (FILE *)pstFileManage->iHandle );
	if( iRet < 0 )
	{
		iFileError = FMERROR_CLOSEFILE;
		iRetVal = COEXIT_FATAL;
	}

	/*** ﾌｧｲﾙﾊﾝﾄﾞﾙ、ｵｰﾌﾟﾝﾓｰﾄﾞのﾘｾｯﾄ	***/
	pstFileManage->iHandle		= cFILEHANDLE_INIT;
	pstFileManage->usOpenMode	= cFLMOD_INIT;

	return( iRetVal );
}
/*D*/
/*[ FILEMAN-USER-005        ]********************************************/
/* 関 数 名 : FileDelete                                                */
/* 機    能 : 指定ﾌｧｲﾙの削除                                            */
/* 引 き 数 : PSZ         pszFileName       削除するﾌｧｲﾙ名              */
/* 戻 り 値 : S4         COEXIT_SUCCESS    正常終了                    */
/*          :             COEXIT_FATAL     異常終了                    */
/* 詳細内容 : 1. 指定ﾌｧｲﾙの管理ﾃｰﾌﾞﾙｱﾄﾞﾚｽを取得する。                   */
/*          : 2. ﾌｧｲﾙを削除する。                                       */
/*          : 3. 管理ﾃｰﾌﾞﾙの取得に失敗したときは異常終了する。          */
/*          : 4. ﾌｧｲﾙがｵｰﾌﾟﾝされていたときは異常終了する。              */
/*          : 5. ﾌｧｲﾙ削除に失敗したときは異常終了する。                 */
/************************************************************************/
/*D*/
S4		FileDelete( PSZ pszFileName )
{
	S4		iRet;		/* 戻り値			*/

	/*** 指定ﾌｧｲﾙの削除		***/
	iRet = remove( pszFileName );
	if( iRet != 0 )
	{
		switch(errno)
		{
		case ENOENT:
			return COEXIT_SUCCESS;
		default:
			break;
		}
		iFileError = FMERROR_DELETEFILE;
		return( COEXIT_FATAL );
	}

	return( COEXIT_SUCCESS );
}
/*D*/
/*[ FILEMAN-USER-007        ]********************************************/
/* 関 数 名 : FileRead                                                  */
/* 機    能 : 指定ｻｲｽﾞ分のﾃﾞｰﾀの読み込み                                */
/* 引 き 数 : HFILE       hFile             ﾌｧｲﾙﾊﾝﾄﾞﾙ                   */
/*          : PVOID       pvArea            ﾃﾞｰﾀ読み込み領域            */
/*          : U4       ulSize            読み込みｻｲｽﾞ                */
/* 戻 り 値 : S4         COEXIT_SUCCESS    正常終了                    */
/*          :             COEXIT_FILEEND    ﾌｧｲﾙｴﾝﾄﾞ                    */
/*          :             COEXIT_FATAL     異常終了                    */
/* 詳細内容 : 1. 指定ﾌｧｲﾙの管理ﾃｰﾌﾞﾙｱﾄﾞﾚｽを取得する。                   */
/*          : 2. ulSizeまたはﾃﾞｰﾀｻｲｽﾞ分のﾊﾞｯﾌｧﾃﾞｰﾀをｺﾋﾟｰする。          */
/*          : 3. ﾊﾞｯﾌｧﾃﾞｰﾀが無くなったときはﾌｧｲﾙから読み込み、繰り返す。*/
/*          : 4. 管理ﾃｰﾌﾞﾙの取得に失敗したときは異常終了する。          */
/*          : 5. ﾌｧｲﾙｵｰﾌﾟﾝされていないときは異常終了する。              */
/*          : 6. ｵｰﾌﾟﾝﾓｰﾄﾞに読み込み許可がないときは異常終了する。      */
/*          : 7. すでにﾌｧｲﾙの最後に達していたときはﾌｧｲﾙｴﾝﾄﾞを返す。     */
/*          : 8. ﾌｧｲﾙから指定ｻｲｽﾞのﾃﾞｰﾀを読み込めないときは、ｴﾗｰﾒｯｾｰｼﾞを*/
/*          :    出力して異常終了する。                                 */
/*          : 9. ﾌｧｲﾙから指定ｻｲｽﾞのﾃﾞｰﾀを読み込む前にﾌｧｲﾙｴﾝﾄﾞに達したと */
/*          :    きは、ｴﾗｰﾒｯｾｰｼﾞを出力して異常終了する。                */
/************************************************************************/
/*D*/
S4		FileRead( HFILE hFile, PVOID pvArea, U4 ulSize, U4 *pulLength )
{
	U4		ulCopySize;	/* ﾊﾞｯﾌｧへのｺﾋﾟｰｻｲｽﾞ		*/
	U4		ulCnt;		/* pvArea への格納ｻｲｽﾞ		*/
	U4		ulDataSize;	/* ﾊﾞｯﾌｧの残りﾃﾞｰﾀｻｲｽﾞ		*/
	S4			iRet;		/* ﾕ-ｻﾞ関数の戻り値		*/
	PFILEMANAGE	 pstFileManage;	/* 読み込むﾌｧｲﾙの管理ﾃｰﾌﾞﾙｱﾄﾞﾚｽ	*/
	if( !initialed )
	{
		iFileError =  FMERROR_NOT_BE_INITIALIZED;
		return COEXIT_FATAL;
	}
	/*** 指定の管理ﾃｰﾌﾞﾙを取得	***/
	pstFileManage = getFileManage( hFile );
	if( pstFileManage == NULL )
	{
		iFileError = FMERROR_ILLEGALHANDLE;
		return( COEXIT_FATAL );
	}

	/*** OPENしていない時は、不可	***/
	if( pstFileManage->iHandle == cFILEHANDLE_INIT )
	{
		iFileError = FMERROR_ACCESS_CLOSEDFILE;
		return( COEXIT_FATAL );
	}

	/*** 読み込み許可でない時、不可	***/
	if( !( pstFileManage->usOpenMode & (FLMOD_READONLY|FLMOD_BIN_READONLY) ) )
	{
		iFileError = FMERROR_READ_WRITEONLYFILE;
		return( COEXIT_FATAL );
	}

	iRet = COEXIT_SUCCESS;
	ulCnt = 0L;

	/*** 指定ｻｲｽﾞREADする		***/
	while( ulCnt < ulSize )
	{
		/*** ﾊﾞｯﾌｧにﾃﾞｰﾀがない時 READする	***/
		ulDataSize = pstFileManage->ulBuffSize - pstFileManage->ulOffset;
		if( ulDataSize == 0L )
		{
			/*** ｷｬｼｭﾊﾞｯﾌｧへの読み込み	***/
			iRet = readCache( pstFileManage );
			if( iRet == COEXIT_FILEEND )
			{
				if( ulCnt != 0L )
				{
					iRet = COEXIT_SUCCESS;
				}
				break;
			}
			else if( iRet != COEXIT_SUCCESS )
			{
				return( iRet );
			}

			/*** ﾃﾞｰﾀｻｲｽﾞを再ｾｯﾄ		***/
			ulDataSize = pstFileManage->ulBuffSize;
		}

		/*** ﾊﾞｯﾌｧｻｲｽﾞで足りない時	***/
		if( ulDataSize < ( ulSize - ulCnt ) )
		{
			/*** ﾊﾞｯﾌｧｻｲｽﾞを取得!!		***/
			ulCopySize = ulDataSize;
		}
		else
		{
			/*** 要求ｻｲｽﾞを取得		***/
			ulCopySize = ulSize - ulCnt;
		}

		memcpy( (PBYTE)pvArea + ulCnt,
			( pstFileManage->pbyCache ) + ( pstFileManage->ulOffset ),
			(size_t)ulCopySize );

		/*** ｵﾌｾｯﾄをREADｻｲｽﾞ分移動する	***/
		pstFileManage->ulOffset += ulCopySize;
		ulCnt += ulCopySize;
	}

	((CHAR*)pvArea)[ulCnt] = '\0' ;

	if( pulLength != NULL )
	{
		*pulLength = ulCnt;
	}

	return( iRet );
}


/*D*/
/*[ FILEMAN-USER-009        ]********************************************/
/* 関 数 名 : FileWrite                                                 */
/* 機    能 : ﾌｧｲﾙへの書き込み                                          */
/* 引 き 数 : HFILE       hFile             ﾌｧｲﾙﾊﾝﾄﾞﾙ                   */
/*          : PVOID       pvArea            書き込みﾃﾞｰﾀ格納ｱﾄﾞﾚｽ       */
/*          : U4       ulSize            書き込みｻｲｽﾞ                */
/* 戻 り 値 : S4         COEXIT_SUCCESS    正常終了                    */
/*          :             COEXIT_FATAL     異常終了                    */
/* 詳細内容 : 1. 指定ﾌｧｲﾙの管理ﾃｰﾌﾞﾙｱﾄﾞﾚｽを取得する。                   */
/*          : 2. ﾊﾞｯﾌｧに書き込みﾃﾞｰﾀを追加する。ﾊﾞｯﾌｧﾃﾞｰﾀが満たされた   */
/*          :    ときはﾌｧｲﾙに出力し、残りのﾃﾞｰﾀをﾊﾞｯﾌｧに格納する。      */
/*          :    ただし、読み書き両用ﾓｰﾄﾞのときはﾊﾞｯﾌｧに格納せず直接ﾌｧｲﾙ*/
/*          :    に出力する。                                           */
/*          : 3. 管理ﾃｰﾌﾞﾙの取得に失敗したときは異常終了する。          */
/*          : 4. ﾌｧｲﾙｵｰﾌﾟﾝされていないときは異常終了する。              */
/*          : 5. ｵｰﾌﾟﾝﾓｰﾄﾞに書き込み許可がないときは異常終了する。      */
/*          : 6. ﾌｧｲﾙへの書き込みに失敗したときは、ﾒｯｾｰｼﾞを出力して異常 */
/*          :    終了する。                                             */
/************************************************************************/
/*D*/
S4		FileWrite( HFILE hFile, PVOID pvArea, U4 ulSize )
{
	U4		ulBufferLarge;	/* 指定ﾌｧｲﾙのｷｬｯｼｭﾊﾞｯﾌｧｻｲｽﾞ	*/
	U4		ulCopySize;	/* ｷｬｯｼｭﾊﾞｯﾌｧへのｺﾋﾟｰｻｲｽﾞ	*/
	U4		ulCnt;		/* pvAreaの処理ｻｲｽﾞ		*/
	U4		ulEmptySize;	/* ｷｬｯｼｭﾊﾞｯﾌｧ空きｴﾘｱｻｲｽﾞ	*/
	S4			iRet;		/* ﾕ-ｻﾞ関数の戻り値		*/
	FILEMANAGE	*pstFileManage;	/* 書き込むﾌｧｲﾙの管理ﾃｰﾌﾞﾙｱﾄﾞﾚｽ	*/
	if( !initialed )
	{
		iFileError =  FMERROR_NOT_BE_INITIALIZED;
		return COEXIT_FATAL;
	}
	/*** 指定の管理ﾃｰﾌﾞﾙを取得	***/
	pstFileManage = getFileManage( hFile );
	if( pstFileManage == NULL )
	{
		iFileError = FMERROR_ILLEGALHANDLE;
		return( COEXIT_FATAL );
	}

	/*** OPENされていない時は、不可	***/
	if( pstFileManage->iHandle == cFILEHANDLE_INIT )
	{
		iFileError = FMERROR_ACCESS_CLOSEDFILE;
		return( COEXIT_FATAL );
	}

	/*** 書き込み許可でない時	***/
	if( !( pstFileManage->usOpenMode & FLMOD_WRITEONLY ) && !( pstFileManage->usOpenMode & FLMOD_BIN_WRITEONLY ) )
	{
		iFileError = FMERROR_WRITE_READONLYFILE;
		return( COEXIT_FATAL );
	}

	/*_____[ 書き込み専用、追加書き込みのとき ]_____________________*/
	ulBufferLarge = (U4)cSIZE_FILECACHE;

	ulCnt = 0L;
	while( ulCnt < ulSize )
	{
		/*** WRITE可能なﾊﾞｯﾌｧｻｲｽﾞ取得	***/
		ulEmptySize = ulBufferLarge
			      - pstFileManage->ulBuffSize;

		/*** ﾊﾞｯﾌｧに空きがない時	***/
		if( ulEmptySize == 0 )
		{
			/*** ｷｬｯｼｭｻｲｽﾞの解消処理	***/
			iRet = flushCache( pstFileManage );
			if( iRet != COEXIT_SUCCESS )
			{
				return( COEXIT_FATAL );
			}

			/*** WRITE可能なﾊﾞｯﾌｧｻｲｽﾞ(全部)	***/
			ulEmptySize = ulBufferLarge;
		}

		/*** 要求ｻｲｽﾞ分格納出来ない時	***/
		if( ulEmptySize < ( ulSize - ulCnt ) )
		{
			/*** 現在のﾊﾞｯﾌｧｻｲｽﾞを取得	***/
			ulCopySize = ulEmptySize;
		}
		else
		{
			/*** 要求ｻｲｽﾞを取得		***/
			ulCopySize = ulSize - ulCnt;
		}

		memcpy( pstFileManage->pbyCache + pstFileManage->ulBuffSize,
			(PBYTE)pvArea + ulCnt,
			(size_t)ulCopySize );

		/*** ｷｬｯｼｭﾊﾞｯﾌｧにｺﾋﾟｰした分をｶｳﾝﾄ	***/
		pstFileManage->ulBuffSize += ulCopySize;
		ulCnt += ulCopySize;
	}

	return( COEXIT_SUCCESS );
}

/*D*/
/*[ FILEMAN-USER-010        ]********************************************/
/* 関 数 名 : FileCheckExists                                           */
/* 機    能 : 指定ﾌｧｲﾙの存在の有無をﾁｪｯｸ                                */
/* 引 き 数 : PSZ         pszFileName       存在ﾁｪｯｸをするﾌｧｲﾙ名        */
/* 戻 り 値 : S4         COEXIT_FOUND      ﾌｧｲﾙが存在する              */
/*          :             COEXIT_NFOUND     ﾌｧｲﾙが存在しない            */
/*          :             COEXIT_FATAL     異常終了                    */
/* 詳細内容 : 1. 指定ﾌｧｲﾙの管理ﾃｰﾌﾞﾙｱﾄﾞﾚｽを取得する。                   */
/*          : 2. ﾌﾙﾊﾟｽﾌｧｲﾙ名でﾌｧｲﾙの有無をﾁｪｯｸする。                    */
/*          : 3. 管理ﾃｰﾌﾞﾙの取得に失敗したときは異常終了する。          */
/************************************************************************/
/*D*/
S4 DLL_EXPORT FileCheckExists( PSZ pszFileName )
{
	struct _filestat	sbuf;		/* ﾌｧｲﾙ情報の取得ｴﾘｱ		*/

	if( pszFileName == NULL || *pszFileName == '\0' )
	{
		return( COEXIT_NFOUND );
	}
	if( getfilestat( pszFileName, &sbuf ) )
	{
		return( COEXIT_NFOUND );
	}

	return( COEXIT_FOUND );
}

/*D*/
/*[ FILEMAN-USER-010        ]********************************************/
/* 関 数 名 : FileCheckDir                                           */
/* 機    能 : 指定フォルダの存在の有無をﾁｪｯｸ                                */
/* 引 き 数 : PSZ         pszFileName       存在ﾁｪｯｸをするﾌｧｲﾙ名        */
/* 戻 り 値 : S4         COEXIT_FOUND      ﾌｧｲﾙが存在する              */
/*          :             COEXIT_NFOUND     ﾌｧｲﾙが存在しない            */
/* 詳細内容 : 1. 指定ﾌｧｲﾙの管理ﾃｰﾌﾞﾙｱﾄﾞﾚｽを取得する。                   */
/*          : 2. ﾌﾙﾊﾟｽﾌｧｲﾙ名でﾌｧｲﾙの有無をﾁｪｯｸする。                    */
/*          : 3. 管理ﾃｰﾌﾞﾙの取得に失敗したときは異常終了する。          */
/************************************************************************/
/*D*/
S4 DLL_EXPORT FileCheckDir( PSZ pszBuf )
{
	struct _filestat	sbuf;		/* ﾌｧｲﾙ情報の取得ｴﾘｱ		*/
	CHAR 			DirPath[OS_FULLPATH+1];
	S4			lStrlen;

	if( pszBuf == NULL )
	{
		return ( COEXIT_NFOUND );
	}

	lStrlen = strlen(pszBuf);

	if(  ( lStrlen == 0 ) || ( lStrlen > OS_FULLPATH ) )
	{
		return ( COEXIT_NFOUND );
	}

	strcpy( DirPath, pszBuf );
	DirPath[lStrlen] = '\0';

	if( lStrlen >= 2 )
	{
#if  (__OS__ == _WINDOWS_XP ) || (__OS__ == _WINDOWS_7)
		if( (!IS_MULTI_CHAR(DirPath[lStrlen-2]))&&( IS_PATH_DELIMITER(DirPath[lStrlen-1]) ) )
		{
			if( DirPath[lStrlen-2] != ':' || DirPath[lStrlen-2] != '.'){
				DirPath[lStrlen-1] = '\0';
			}
		}
		else if( (!IS_MULTI_CHAR(DirPath[lStrlen-2]))&&( DirPath[lStrlen-1] == ':' ) )
		{
			DirPath[lStrlen] = PATH_DELIMITER;
			DirPath[lStrlen + 1] = '\0';
		}
#endif
	}
	else if( lStrlen == 1 )
	{
		if ( IS_PATH_DELIMITER(DirPath[lStrlen-1]) )
		{
			return( COEXIT_FOUND );
		}
	}

	if( !( getfilestat( DirPath, &sbuf ) ) )
	{
		if( IS_FOLDER(sbuf) )
		{
			return ( COEXIT_FOUND );
		}
	}

	return( COEXIT_NFOUND );
}

/*D*/
/*[ FILEMAN-USER-011        ]********************************************/
/* 関 数 名 : FileGetFullPath                                           */
/* 機    能 : 指定ﾌｧｲﾙのﾌﾙﾊﾟｽﾌｧｲﾙ名取得                                 */
/* 引 き 数 : HFILE       hFile             ﾌｧｲﾙﾊﾝﾄﾞﾙ                   */
/*          : PUCHAR      pszBuff           ﾊﾞｯﾌｧﾎﾟｲﾝﾀ                  */
/*          : U2      usBufSize         ﾊﾞｯﾌｧｻｲｽﾞ                   */
/* 戻 り 値 : BOOL        TRUE              正常終了                    */
/*          :             FALSE             異常終了                    */
/* 詳細内容 : 1. 指定ﾌｧｲﾙのﾌｧｲﾙ情報を取得する。                         */
/*          : 2. ﾌﾙﾊﾟｽﾌｧｲﾙ名を取得する。                                */
/************************************************************************/
/*D*/
S4		FileGetFullPath( HFILE hFile, CHAR* pszBuff, U2 usBufSize )
{
	PFILEMANAGE	pstFileManage;	/* 取得したいﾌｧｲﾙのﾃｰﾌﾞﾙｱﾄﾞﾚｽ	*/
	if( !initialed )
	{
		iFileError =  FMERROR_NOT_BE_INITIALIZED;
		return COEXIT_FATAL;
	}
	/*** 指定のﾌｧｲﾙ情報を取得	***/
	pstFileManage = getFileManage( hFile );
	if( pstFileManage == NULL )	/* ﾃｰﾌﾞﾙｱﾄﾞﾚｽ取得に失敗したとき	*/
	{
		iFileError = FMERROR_ILLEGALHANDLE;
		return( COEXIT_FATAL );
	}

	/*** ﾌﾙﾊﾟｽﾌｧｲﾙ名取得	***/
	memset( pszBuff, '\0', usBufSize );

	strncpy( pszBuff, pstFileManage->szFullPath, (size_t)( usBufSize - 1 ) );

	return( COEXIT_SUCCESS );
}

/*D*/
/*[ FILEMAN-USER-012        ]********************************************/
/* 関 数 名 : FilePickUpName                                            */
/* 機    能 : ﾌﾙﾊﾟｽ文字列からﾌｧｲﾙ名のみを切り出す                       */
/* 引 き 数 : PSZ       pszFullPath    ﾌﾙﾊﾟｽ文字列                      */
/* 戻 り 値 : PSZ                      ﾌｧｲﾙ名文字列へのﾎﾟｲﾝﾀ            */
/* 詳細内容 : 1.ﾌﾙﾊﾟｽ文字列の中から、ﾌｧｲﾙ名を示す位置のﾎﾟｲﾝﾀを返す。    */
/************************************************************************/
/*D*/
PSZ		FilePickUpName( PSZ pszFullPath )
{
	PSZ		p;		/* 作業用のﾎﾟｲﾝﾀ		*/

	if( pszFullPath )
	{
	     p = (PSZ)getPathDelimiter( pszFullPath, FALSE );

	    if( p != NULL )
	    {
	    	pszFullPath = p + 1;
	    }
		else
		{
#if  (__OS__ == _WINDOWS_XP ) || (__OS__ == _WINDOWS_7)
			if( ( *pszFullPath == '\\' ) || ( *pszFullPath == '/' ) )
#else
			if(  *pszFullPath == '/'  )
#endif
			{
				pszFullPath += 1;
			}
		}
	}
	return( pszFullPath );
}
/*D*/
/*[ FILEMAN-USER-019        ]********************************************/
/* 関 数 名 : FileReadWholeLine                                         */
/* 機    能 : ﾌｧｲﾙからの１行読み込み(１行まるまる読み込み)              */
/* 引 き 数 : HFILE       hFile             ﾌｧｲﾙﾊﾝﾄﾞﾙ                   */
/*          : PSZ         *ppszLine         読み込んだ行ﾊﾞｯﾌｧのｴﾘｱ      */
/*          : PULONG      pulSize           読み込んだｻｲｽﾞ(ﾊﾞｲﾄ数)      */
/* 戻 り 値 : S4         COEXIT_SUCCESS    正常終了                    */
/*          :             COEXIT_FILEEND    ﾌｧｲﾙｴﾝﾄﾞ                    */
/*          :             COEXIT_FATAL     異常終了                    */
/* 詳細内容 : 1. 改行ｺｰﾄﾞが出現するまで読み込みを続ける。               */
/*          : 2. 読み込んだ内容はﾃﾝﾎﾟﾗﾘﾊﾞｯﾌｧに保存する。                */
/*          : 3. ﾊﾞｯﾌｧのﾎﾟｲﾝﾀ＆読み込みｻｲｽﾞを返す。                     */
/*          : 4. 改行ｺｰﾄﾞなしでﾌｧｲﾙｴﾝﾄﾞの場合、末尾に改行ｺｰﾄﾞはない。   */
/************************************************************************/
/*D*/
S4		FileReadWholeLine( HFILE hFile, PSZ *ppszLine, U4* pulSize )
{
	S4			rc;			/* 戻り値					*/
	U4		siz;		/* 読み込みｻｲｽﾞ			*/
	U4		ulSize;		/* 読み込んだ文字列のｻｲｽﾞ	*/

	if( !initialed )
	{
		iFileError =  FMERROR_NOT_BE_INITIALIZED;
		return COEXIT_FATAL;
	}
	/*_____[ 読み込みｻｲｽﾞの初期化 ]_________________________________*/
	if( readbuf_usedsize > 0 )
	{
		memset( readbuf, 0, readbuf_usedsize );
		readbuf_usedsize = 0;
	}
	ulSize = 0UL;
	/*_____[ 改行までの読み込み処理 ]_______________________________*/
	rc = fileReadLine( hFile, uchFileTmpBuff, (U4)sizeof(uchFileTmpBuff), &siz );
	while( rc == COEXIT_SUCCESS )
	{
		if( ulSize + siz >= cSIZE_READBUF )
		{
			rc = COEXIT_FATAL;
			iFileError = FMERROR_READ_HUGE_ROW;
			break;
		}
		/* 読み込んだ分をﾊﾞｯﾌｧに追加				*/
		memcpy( &readbuf[ulSize], uchFileTmpBuff, siz );
		ulSize += siz;
		/* 改行で終わっているときに読み込み終了			*/
		if( uchFileTmpBuff[siz-1] == '\n' )
		{
			break;
		}

		rc = fileReadLine( hFile, uchFileTmpBuff, (U4)sizeof(uchFileTmpBuff), &siz );
	}
	if( rc == COEXIT_FILEEND )
	{
		/* ﾌｧｲﾙ終了でも読み込んだ文字があればﾌｧｲﾙ終了にしない	*/
		if( ulSize != 0UL )
		{
			rc = COEXIT_SUCCESS;
		}
	}

	/*_____[ 読み込みｴﾘｱ＆ｻｲｽﾞを戻りにｾｯﾄ ]_________________________*/
	if( ppszLine != NULL )
	{
		*ppszLine = &readbuf[0];
	}
	if( pulSize != NULL )
	{
		*pulSize = ulSize;
	}
	readbuf_usedsize = ulSize+1;
	return( rc );
}
/*D*/
/**************************************************************************
* 関 数 名 : FileGetLastError
* 機    能 : ファイルをアクセスする時に、エラーが起きたら、最後のエラーの原因を取得する
* 引    数 : なし
* 戻 り 値 : static変数iFileErrorの値
************************************************************************/
/*D*/
S4			FileGetLastError( VOID ){
	S4		iFile;
	iFile = iFileError?(iFileError | (errno<<16)):iFileError;
	iFileError = 0;
	return( iFile);
}
/*D*/
/*[ FILEMAN-USER-013        ]********************************************/
/* 関 数 名 : FileFindOpen                                              */
/* 機    能 : ﾌｧｲﾙ検索の初期処理                                        */
/* 引 き 数 : PSZ       pszStartDir    検索開始ﾃﾞｨﾚｸﾄﾘ                  */
/*          : PFILEFIND pstFind        検索処理用の内部情報             */
/* 戻 り 値 : INT       COEXIT_SUCCESS 正常終了                         */
/*          :           COEXIT_FATAL  異常終了                         */
/* 詳細内容 : 1. 指定ﾃﾞｨﾚｸﾄﾘのﾃﾞｨﾚｸﾄﾘ情報を検索する。                   */
/*          : 2. 検索情報は内部情報に保存しておく。                     */
/************************************************************************/
/*D*/
S4	FileFindOpen( PSZ pszStartDir, PFILEFIND pstFind )
{
	if(( pszStartDir != NULL ) && ( sizeof(pstFind->szStart) <= strlen(pszStartDir) ) )
	{
		iFileError = FMERROR_ILLEGALPATH;
		return( COEXIT_FATAL );
	}
	if( pstFind == NULL )
	{
		iFileError = FMERROR_SEARCHDIR;
		return( COEXIT_FATAL );
	}

	if( ( pszStartDir != NULL ) && (*pszStartDir != '\0' ) )
	{
		strcpy( pstFind->szStart, pszStartDir );
#if  (__OS__ == _WINDOWS_XP ) || (__OS__ == _WINDOWS_7)
		if ( pszStartDir[strlen(pszStartDir)-1] != '/' &&
				pszStartDir[strlen(pszStartDir)-1] != '\\' )
#else
		if ( pszStartDir[strlen(pszStartDir)-1] != '/' )
#endif
		{
			pstFind->szStart[strlen(pszStartDir)] = '/';
			pstFind->szStart[strlen(pszStartDir)+1] = '\0';
		}
	}
	else
	{
		strcpy( pstFind->szStart, "./" );
	}


	/* ﾃﾞｨﾚｸﾄﾘをｵｰﾌﾟﾝ(ﾃﾞｨﾚｸﾄﾘﾊﾝﾄﾞﾙを取得)				*/
	pstFind->handle = (PVOID)opendir( pstFind->szStart );
	if( pstFind->handle == NULL )
	{
		if( ( errno == ENOENT ) || ( errno == ENOTDIR ) )
		{
			iFileError = FMERROR_SEARCHDIR;
			return( COEXIT_FATAL );
		}
	}

	/* 検索情報の保存ｴﾘｱを初期化					*/
	memset( (void*)pstFind->szFound, '\0', OS_FULLPATH );

	return( COEXIT_SUCCESS );
}
/*D*/
/*[ FILEMAN-USER-014        ]********************************************/
/* 関 数 名 : FileFindClose                                             */
/* 機    能 : ﾌｧｲﾙ検索の終了処理                                        */
/* 引 き 数 : PFILEFIND pstFind        検索処理用の内部情報             */
/* 戻 り 値 : INT       COEXIT_SUCCESS 正常終了                         */
/*          :           COEXIT_FATAL  異常終了                         */
/* 詳細内容 : 1. 内部情報で指定されるﾒﾓﾘｴﾘｱを開放する。                 */
/*          : 2. 内部情報をｸﾘｱする。                                    */
/************************************************************************/
/*D*/
S4	 FileFindClose( PFILEFIND pstFind )
{
	/* ﾃﾞｨﾚｸﾄﾘをｸﾛｰｽﾞ(ﾃﾞｨﾚｸﾄﾘﾊﾝﾄﾞﾙを開放)				*/
	if( pstFind )
	{
		if( pstFind->handle != NULL )
		{
			closedir( pstFind->handle );
			pstFind->handle = NULL;
		}
	    /* 検索情報の保存ｴﾘｱを初期化					*/
	    memset( pstFind->szStart, '\0', sizeof(pstFind->szStart) );
	    memset( pstFind->szFound, '\0', sizeof(pstFind->szFound) );
	}
	return( COEXIT_SUCCESS );
}
/*D*/
/*[ FILEMAN-USER-015        ]********************************************/
/* 関 数 名 : FileFindFirst                                             */
/* 機    能 : ﾌｧｲﾙ検索：最初のﾌｧｲﾙを取得                                */
/* 引 き 数 : PFILEFIND pstFind        検索処理用の内部情報             */
/* 戻 り 値 : S4       COEXIT_FOUND   ﾌｧｲﾙあり                         */
/*          :           COEXIT_NFOUND  ﾌｧｲﾙなし                         */
/* 詳細内容 : 1. 内部情報を最初に戻す。                                 */
/*          : 2. 次のﾌｧｲﾙ名を取得する。                                 */
/************************************************************************/
/*D*/
S4	 FileFindFirst( PFILEFIND pstFind )
{
	if( pstFind == NULL || pstFind->handle == FILE_HANDLE_NULL )
	{
		return( COEXIT_NFOUND );
	}
	/* 次のﾌｧｲﾙを取得						*/
	return( FileFindNext( pstFind ) );
}
/*D*/
/*[ FILEMAN-USER-016        ]********************************************/
/* 関 数 名 : FileFindNext                                              */
/* 機    能 : ﾌｧｲﾙ検索：次のﾌｧｲﾙを取得                                  */
/* 引 き 数 : PFILEFIND pstFind        検索処理用の内部情報             */
/* 戻 り 値 : S4       COEXIT_FOUND   ﾌｧｲﾙあり                         */
/*          :           COEXIT_NFOUND  ﾌｧｲﾙなし                         */
/* 詳細内容 : 1. ﾃﾞｨﾚｸﾄﾘ情報を読みだし、ﾌｧｲﾙ名を検索する。              */
/*          : 2. 発見したﾌｧｲﾙ名をﾊﾞｯﾌｧにｺﾋﾟｰする。                      */
/************************************************************************/
/*D*/
S4	 FileFindNext( PFILEFIND pstFind )
{
	struct _filestat	sbuf;		/* ﾌｧｲﾙ情報の取得ｴﾘｱ		*/
	size_t		s_size ;

	struct dirent	*pstEnt;	/* ﾃﾞｨﾚｸﾄﾘのｴﾝﾄﾘｰ情報		*/
	if( pstFind == NULL || pstFind->handle == FILE_HANDLE_NULL )
	{
		return( COEXIT_NFOUND );
	}
	/* ﾃﾞｨﾚｸﾄﾘのｴﾝﾄﾘｰ情報を読み込み					*/
	pstEnt = readdir( pstFind->handle );
	while( pstEnt != NULL )
	{
		if( ( strcmp( pstEnt->d_name, "." ) )
		 && ( strcmp( pstEnt->d_name, ".." ) ) )
		{
			break;		/* ﾌｧｲﾙがあるまで読み込み	*/
		}
		pstEnt = readdir( (DIR*)pstFind->handle );
	}
	if( pstEnt == NULL )
	{
		return( COEXIT_NFOUND );/* 最後まで読み込んでしまった	*/
	}

	s_size = strlen( pstFind->szStart ) + strlen( pstEnt->d_name ) ;
	/* ﾃﾞｨﾚｸﾄﾘ名をつなげたﾌｧｲﾙ名を作成				*/
	if( pstFind->szStart[strlen(pstFind->szStart)-1] == '/' )
	{
		if ( s_size >= OS_FULLPATH )
		{
			iFileError = FMERROR_ILLEGALPATH;
			return ( COEXIT_FATAL ) ;
		}

		sprintf( pstFind->szFound, "%s%s", pstFind->szStart, pstEnt->d_name );
	}
	else
	{
		if ( ( s_size + 1 ) >= OS_FULLPATH )
		{
			iFileError = FMERROR_ILLEGALPATH;
			return ( COEXIT_FATAL ) ;
		}

		sprintf( pstFind->szFound, "%s/%s", pstFind->szStart, pstEnt->d_name );
	}

	/* 見つかったものがﾃﾞｨﾚｸﾄﾘがどうかをﾁｪｯｸ			*/
	if( getfilestat( pstFind->szFound, &sbuf ) < 0 )
	{
		iFileError = FMERROR_SEARCHDIR;
		return( COEXIT_FATAL );
	}

	if( IS_FOLDER(sbuf) )
	{
		pstFind->fDir = TRUE;	/* ﾃﾞｨﾚｸﾄﾘでした		*/
	}
	else
	{
		pstFind->fDir = FALSE;	/* ﾃﾞｨﾚｸﾄﾘではありませんでした	*/
	}

	return( COEXIT_FOUND );
}
/*D*/
/*[ FILEMAN-USER-016        ]********************************************/
/* 関 数 名 : FileFindNext                                              */
/* 機    能 : ﾌｧｲﾙ検索：次のﾌｧｲﾙを取得                                  */
/* 引 き 数 : PFILEFIND pstFind        検索処理用の内部情報             */
/* 戻 り 値 : S4       COEXIT_FOUND   ﾌｧｲﾙあり                         */
/*          :           COEXIT_NFOUND  ﾌｧｲﾙなし                         */
/* 詳細内容 : 1. ﾃﾞｨﾚｸﾄﾘ情報を読みだし、ﾌｧｲﾙ名を検索する。              */
/*          : 2. 発見したﾌｧｲﾙ名をﾊﾞｯﾌｧにｺﾋﾟｰする。                      */
/************************************************************************/
/*D*/
PSZ   FilePickUpExt( PSZ filepath )
{
	register PSZ p;
	p = filepath;
	if( str_length( p ) == 0 )
	{
		return p;
	}
	p = filepath + strlen(filepath);
	while( ( p - filepath ) > 0 )
	{
		if( IS_PATH_DELIMITER(*p))
		{
			return filepath + strlen(filepath);
		}
		else if( *p == '.' )
		{
			if( IS_PATH_DELIMITER(*(p-1)) || IS_MULTI_CHAR( *(p-1)) )
			{
				p--;
			}
			else
			{
				return (p+1);
			}
		}
		p--;
	}
	return filepath + strlen(filepath);
}
/*D*/
/*[ FILEMAN-USER-017        ]********************************************/
/* 関 数 名 : FileGetSize                                              */
/************************************************************************/
/*D*/
U4  FileGetSize( PSZ filepath )
{
	struct _filestat	sbuf;		/* ﾌｧｲﾙ情報の取得ｴﾘｱ		*/
	if( str_length( filepath ) == 0 )
	{
		return 0;
	}
	/* 見つかったものがﾃﾞｨﾚｸﾄﾘがどうかをﾁｪｯｸ			*/
	if( getfilestat( filepath, &sbuf ) < 0 )
	{
		return 0;
	}
	return sbuf.st_size;
}
/*D*/
/*[ FILEMAN-USER-017        ]********************************************/
/* 関 数 名 : FileGetModifyTime                                              */
/************************************************************************/
/*D*/
S4  FileGetModifyTime( PSZ filepath )
{
	struct _filestat	sbuf;		/* ﾌｧｲﾙ情報の取得ｴﾘｱ		*/
	if( str_length( filepath ) == 0 )
	{
		return -1;
	}
	/* 見つかったものがﾃﾞｨﾚｸﾄﾘがどうかをﾁｪｯｸ			*/
	if( getfilestat( filepath, &sbuf ) < 0 )
	{
		return -1;
	}
	return sbuf.st_mtime;
}
/**********************[end of file_access.c]*****************/
